package com.gitee.feizns.dynamic;

import com.gitee.feizns.dynamic.function.ThrowableRunnable;
import com.gitee.feizns.dynamic.function.ThrowableSupplier;
import com.gitee.feizns.dynamic.function.TryCatch;

/**
 * <b>异常处理常用操作工具类</b>
 *
 * @see Exception
 * @see Throwable
 * @author feizns
 * @since 2019/6/21
 */
public abstract class Ex {

    /**
     * <b>异常链中查找指定类型的异常</b>
     *
     * <p>
     *     如果{@code throwable}的异常链中是有匹配{@code courseClasses}类型中的任意一个则返回该原因对象、否则返回{@code null}
     * </p>
     *
     * @param throwable 所需要查找的异常
     * @param courseClasses 查找的原因类型
     * @return 符合查找原因类型的异常对象
     */
    @SafeVarargs
    public static Throwable findCourse(Throwable throwable, Class<? extends Throwable>... courseClasses) {
        Throwable course = throwable;
        while ( course != null ) {
            for (Class<? extends Throwable> courseClass : courseClasses) {
                if ( courseClass.isAssignableFrom(course.getClass()) )
                    return course;
            }
            course = course.getCause();
        }
        return null;
    }

    /**
     * 尝试 Catch
     * @param supplier 供应商
     * @return {@link TryCatch}<{@link T}>
     */
    public static <T> TryCatch<T> tryCatch(ThrowableSupplier<T> supplier) {
        return new TryCatch<>(supplier);
    }

    /**
     * 尝试 Catch
     * @param runnable 可运行
     * @return {@link TryCatch}<{@link Void}>
     */
    public static TryCatch<Void> tryCatch(ThrowableRunnable runnable) {
        return new TryCatch<>(runnable);
    }

}
